#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
基本用法示例

该示例展示了配置管理模块的基本用法，包括：
1. 加载不同格式的配置文件
2. 获取配置项
3. 修改配置项
4. 保存配置
5. 自动重新加载
6. 配置加密
7. 配置验证
8. 单例模式
"""

import os
import sys
import time

# 添加项目根目录到Python路径
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../')))

from modules.config.config_manager import ConfigManager, get_config_manager, ConfigValidator


def create_example_config_files():
    """创建示例配置文件"""
    # 创建示例目录
    example_dir = os.path.dirname(os.path.abspath(__file__))
    os.makedirs(example_dir, exist_ok=True)
    
    # 创建JSON配置文件
    json_config = {
        "app": {
            "name": "示例应用",
            "version": "1.0.0",
            "debug": True
        },
        "database": {
            "host": "localhost",
            "port": 3306,
            "username": "root",
            "password": "password",
            "database": "example"
        },
        "logging": {
            "level": "INFO",
            "file": "logs/app.log",
            "max_size": 10485760,
            "backup_count": 5
        }
    }
    
    with open(os.path.join(example_dir, 'config.json'), 'w', encoding='utf-8') as f:
        import json
        json.dump(json_config, f, indent=2, ensure_ascii=False)
    
    # 创建YAML配置文件
    yaml_config = """# 服务器配置
server:
  host: 0.0.0.0
  port: 8080
  workers: 4
  timeout: 30

# 缓存配置
cache:
  enabled: true
  type: redis
  host: localhost
  port: 6379
  ttl: 3600
"""
    
    with open(os.path.join(example_dir, 'config.yaml'), 'w', encoding='utf-8') as f:
        f.write(yaml_config)
    
    # 创建INI配置文件
    ini_config = """[smtp]
server = smtp.example.com
port = 587
username = user@example.com
password = password
use_tls = true

[notification]
enabled = true
recipients = admin@example.com, support@example.com
subject_prefix = [ALERT]
"""
    
    with open(os.path.join(example_dir, 'config.ini'), 'w', encoding='utf-8') as f:
        f.write(ini_config)
    
    # 创建ENV配置文件
    env_config = """# 环境变量配置
APP_ENV=production
DEBUG=false
SECRET_KEY=your-secret-key-here
API_TIMEOUT=30
MAX_CONNECTIONS=100
"""
    
    with open(os.path.join(example_dir, 'config.env'), 'w', encoding='utf-8') as f:
        f.write(env_config)
    
    print("示例配置文件已创建")


def basic_usage():
    """基本用法示例"""
    # 创建配置管理器实例
    config = ConfigManager()
    
    # 获取示例文件路径
    example_dir = os.path.dirname(os.path.abspath(__file__))
    json_config_path = os.path.join(example_dir, 'config.json')
    yaml_config_path = os.path.join(example_dir, 'config.yaml')
    ini_config_path = os.path.join(example_dir, 'config.ini')
    env_config_path = os.path.join(example_dir, 'config.env')
    
    # 加载JSON配置文件
    print("\n加载JSON配置文件...")
    config.load_config(json_config_path)
    
    # 加载YAML配置文件（使用命名空间）
    print("加载YAML配置文件...")
    config.load_config(yaml_config_path, namespace='yaml_config')
    
    # 加载INI配置文件（使用命名空间）
    print("加载INI配置文件...")
    config.load_config(ini_config_path, namespace='ini_config')
    
    # 加载ENV配置文件（使用命名空间）
    print("加载ENV配置文件...")
    config.load_config(env_config_path, namespace='env_config')
    
    # 获取配置项
    app_name = config.get('app.name')
    app_version = config.get('app.version')
    db_host = config.get('database.host')
    db_port = config.get_int('database.port')
    server_host = config.get('yaml_config.server.host')
    server_port = config.get_int('yaml_config.server.port')
    smtp_server = config.get('ini_config.smtp.server')
    app_env = config.get('env_config.APP_ENV')
    
    print("\n获取配置项:")
    print(f"应用名称: {app_name}")
    print(f"应用版本: {app_version}")
    print(f"数据库主机: {db_host}")
    print(f"数据库端口: {db_port}")
    print(f"服务器主机: {server_host}")
    print(f"服务器端口: {server_port}")
    print(f"SMTP服务器: {smtp_server}")
    print(f"应用环境: {app_env}")
    
    # 修改配置项
    print("\n修改配置项...")
    config.set('app.version', '1.1.0')
    config.set('database.password', 'new_password')
    config.set('yaml_config.server.port', 9090)
    
    # 获取修改后的配置项
    new_app_version = config.get('app.version')
    new_db_password = config.get('database.password')
    new_server_port = config.get_int('yaml_config.server.port')
    
    print("修改后的配置项:")
    print(f"新应用版本: {new_app_version}")
    print(f"新数据库密码: {new_db_password}")
    print(f"新服务器端口: {new_server_port}")
    
    # 保存配置到新文件
    new_json_config_path = os.path.join(example_dir, 'new_config.json')
    new_yaml_config_path = os.path.join(example_dir, 'new_config.yaml')
    
    print("\n保存配置...")
    config.save_config(new_json_config_path)
    print(f"配置已保存到: {new_json_config_path}")
    
    config.save_config(new_yaml_config_path, namespace='yaml_config')
    print(f"YAML配置已保存到: {new_yaml_config_path}")


def auto_reload_example():
    """自动重新加载示例"""
    # 创建配置管理器实例
    config = ConfigManager()
    
    # 获取示例文件路径
    example_dir = os.path.dirname(os.path.abspath(__file__))
    json_config_path = os.path.join(example_dir, 'config.json')
    
    # 加载JSON配置文件并启用自动重新加载
    print("\n加载JSON配置文件并启用自动重新加载...")
    config.load_config(json_config_path, auto_reload=True, reload_interval=1)
    
    # 获取初始配置
    app_name = config.get('app.name')
    app_version = config.get('app.version')
    
    print(f"初始应用名称: {app_name}")
    print(f"初始应用版本: {app_version}")
    
    # 提示用户修改配置文件
    print("\n请在5秒内手动修改配置文件: " + json_config_path)
    print("将 'app.name' 修改为 '新应用名称'")
    
    # 等待一段时间，让用户有机会修改文件
    for i in range(5):
        print(f"等待中... {5-i} 秒")
        time.sleep(1)
    
    # 获取可能已更新的配置
    new_app_name = config.get('app.name')
    new_app_version = config.get('app.version')
    
    print(f"\n更新后的应用名称: {new_app_name}")
    print(f"更新后的应用版本: {new_app_version}")
    
    # 禁用自动重新加载
    config.disable_auto_reload()
    print("已禁用自动重新加载")


def encryption_example():
    """加密配置示例"""
    # 创建配置管理器实例
    config = ConfigManager()
    
    # 设置加密器
    secret_key = "my-secret-key"
    config.set_encryptor(secret_key)
    
    # 加密敏感配置
    print("\n加密敏感配置...")
    config.set_encrypted('database.password', 'super-secret-password')
    config.set_encrypted('api.key', 'api-key-12345')
    
    # 获取加密后的值
    encrypted_password = config.get('database.password')
    encrypted_api_key = config.get('api.key')
    
    print(f"加密后的密码: {encrypted_password}")
    print(f"加密后的API密钥: {encrypted_api_key}")
    
    # 解密值
    decrypted_password = config.get_encrypted('database.password')
    decrypted_api_key = config.get_encrypted('api.key')
    
    print("\n解密后的值:")
    print(f"解密后的密码: {decrypted_password}")
    print(f"解密后的API密钥: {decrypted_api_key}")
    
    # 保存加密配置
    example_dir = os.path.dirname(os.path.abspath(__file__))
    encrypted_config_path = os.path.join(example_dir, 'encrypted_config.json')
    
    config.save_config(encrypted_config_path)
    print(f"加密配置已保存到: {encrypted_config_path}")


def validation_example():
    """配置验证示例"""
    # 创建配置管理器实例
    config = ConfigManager()
    
    # 注册验证器
    config.register_validator('app.name', ConfigValidator(str, required=True))
    config.register_validator('app.version', ConfigValidator(str, required=True))
    config.register_validator('app.debug', ConfigValidator(bool, default=False))
    config.register_validator('database.port', ConfigValidator(
        int, 
        required=True,
        validator=lambda x: 1024 <= x <= 65535,
        description="数据库端口必须在1024-65535之间"
    ))
    config.register_validator('logging.level', ConfigValidator(
        str,
        required=True,
        validator=lambda x: x in ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'),
        description="日志级别必须是有效的级别名称"
    ))
    
    # 设置有效的配置
    print("\n设置有效的配置...")
    config.set('app.name', '示例应用')
    config.set('app.version', '1.0.0')
    config.set('app.debug', True)
    config.set('database.port', 3306)
    config.set('logging.level', 'INFO')
    
    # 验证配置
    valid, errors = config.validate_config()
    print(f"配置是否有效: {valid}")
    
    if not valid:
        print("验证错误:")
        for key, error in errors.items():
            print(f"  {key}: {error}")
    
    # 设置无效的配置
    print("\n设置无效的配置...")
    config.set('database.port', 80)  # 端口号太小
    config.set('logging.level', 'TRACE')  # 无效的日志级别
    
    # 验证配置
    valid, errors = config.validate_config()
    print(f"配置是否有效: {valid}")
    
    if not valid:
        print("验证错误:")
        for key, error in errors.items():
            print(f"  {key}: {error}")


def singleton_example():
    """单例模式示例"""
    # 获取默认配置管理器实例
    config1 = get_config_manager()
    
    # 设置一些配置
    config1.set('app.name', '单例示例')
    config1.set('app.version', '1.0.0')
    
    # 获取另一个默认配置管理器实例（应该是同一个实例）
    config2 = get_config_manager()
    
    # 验证两个实例共享相同的配置
    app_name1 = config1.get('app.name')
    app_name2 = config2.get('app.name')
    
    print(f"\nconfig1.app.name: {app_name1}")
    print(f"config2.app.name: {app_name2}")
    print(f"config1 和 config2 是同一个实例: {config1 is config2}")
    
    # 获取不同名称的配置管理器实例
    config3 = get_config_manager('another')
    config3.set('app.name', '另一个示例')
    
    # 验证不同名称的实例有不同的配置
    app_name3 = config3.get('app.name')
    
    print(f"\nconfig3.app.name: {app_name3}")
    print(f"config1 和 config3 是同一个实例: {config1 is config3}")


if __name__ == '__main__':
    # 创建示例配置文件
    create_example_config_files()
    
    # 运行示例
    basic_usage()
    auto_reload_example()
    encryption_example()
    validation_example()
    singleton_example()